package com.bwie.service.impl;

import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bwie.domain.TbLog;
import com.bwie.domain.TbProd;
import com.bwie.mapper.TbProdMapper;
import com.bwie.service.TbProdService;
import com.bwie.utils.R;
import com.bwie.vo.MessageVo;
import com.bwie.vo.PageInfoVo;
import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.concurrent.FailureCallback;
import org.springframework.util.concurrent.SuccessCallback;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Validation;
import java.util.*;

/**
 * @author 军哥
 * @version 1.0
 * @description: TODO
 * @date 2024/10/16 14:31
 */

@Service
public class TbProdServiceImpl implements TbProdService {

    @Autowired
    TbProdMapper tbProdMapper;

    @Autowired
    FastFileStorageClient fastFileStorageClient;

    @Autowired
    KafkaTemplate kafkaTemplate;

    @Autowired
    HttpServletRequest httpServletRequest;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public R getProdList(PageInfoVo pageInfoVo) {
        // 构造分页
        Page<TbProd> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());

        // 构造查询条件
        QueryWrapper<TbProd> wrapper = new QueryWrapper<>();
        if(pageInfoVo.getTypeId() != null) {
            // 根据商品类型进行查询
            wrapper.lambda().eq(TbProd::getProdType, pageInfoVo.getTypeId());
        }
        if(!StringUtils.isEmpty(pageInfoVo.getKeyWord())) {
            // 根据商品的名称进行模糊查询
            wrapper.lambda().like(TbProd::getProdName, pageInfoVo.getKeyWord());
        }

        // 根据商品ID倒序排列
        wrapper.lambda().orderByDesc(TbProd::getProdId);


        IPage<TbProd> tbProdIPage = tbProdMapper.selectPage(page, wrapper);

        // 进行是否过期判断
        Date date = new Date();
        for (TbProd tbProd : tbProdIPage.getRecords()) {
            // 判断是否过期
            if(tbProd.getCreateTime().getTime() < date.getTime()) {
                // 过期
                tbProd.setProdStatus(1);
            }
            else {
                // 未过期
                tbProd.setProdStatus(0);
            }
        }

        Validator.isMobile("12345678901");
        Validator.isEmail("12345678901@qq.com");
        Validator.isChinese("中国");

        return R.OK(tbProdIPage);
    }

    @Override
    public R checkStock(Integer prodId, Integer prodCount) {
        // 获取商品库存信息
        TbProd tbProd = tbProdMapper.selectById(prodId);
        if(tbProd == null) {
            return R.ERROR(404, "商品不存在");
        }
        // 判断库存
        if(tbProd.getProdCount() < prodCount) {
            return R.ERROR(500, "库存不足");
        }

        // 扣减库存
        // TODO

        return R.OK();
    }

    @Override
    public R addProd(TbProd tbProd) {
        // -- 检查是否是否重复
        TbProd prod = tbProdMapper.selectOne(
                new QueryWrapper<TbProd>().lambda().eq(TbProd::getProdName, tbProd.getProdName())
        );
        if(prod != null) {
            return R.ERROR(500, "商品名称重复");
        }

        //-- 添加商品
        tbProd.setCreateTime(new Date());
        tbProd.setShopId(1);
        tbProdMapper.insert(tbProd);

        //-- 记录日志
        MessageVo messageVo = new MessageVo();
        TbLog tbLog = new TbLog();


        // 生成消息的唯一ID
        String msgId = UUID.randomUUID().toString();

        // 同意token获取用户信息
        String token = httpServletRequest.getHeader("token");
        if(token != null) {
            Claims body = Jwts.parser().setSigningKey("123456").parseClaimsJws(token).getBody();
            Integer userId = body.get("userId", Integer.class);
            tbLog.setOptUser(userId);

            String userName = body.get("userName", String.class);
            tbLog.setNickName(userName);
        }

        // 获取ip
        String ip = httpServletRequest.getRemoteAddr();

        // 构造消息体
        tbLog.setLogIp(ip);
        tbLog.setOptTime(new Date());
        tbLog.setOptContent("商品添加：" + tbProd.getProdName());

        //
        String msgBody = JSON.toJSONString(tbLog);

        messageVo.setMsgId(msgId);
        messageVo.setMsgBody(msgBody);

        // 发送消息之前，需要把消息的唯一ID，存入缓存，防止消息重复消费
        stringRedisTemplate.opsForValue().set(msgId, msgBody);

        kafkaTemplate.send("topic-log", JSON.toJSONString(messageVo)).addCallback(
                new SuccessCallback() {
                    @Override
                    public void onSuccess(Object o) {
                        System.out.println("消息发送成功");
                    }
                },
                new FailureCallback() {
                    @Override
                    public void onFailure(Throwable throwable) {
                        System.out.println("消息发送失败，再次发送");
                        kafkaTemplate.send("topic-log", JSON.toJSONString(messageVo));
                    }
                }
        );

        return R.OK();
    }

    @Override
    public R delProd(Integer prodId) {
        tbProdMapper.deleteById(prodId);
        return R.OK();
    }

    @Override
    public R updateProd(TbProd tbProd) {
        // 判断商品是否存在
        TbProd prod = tbProdMapper.selectById(tbProd.getProdId());
        if(prod == null) {
            return R.ERROR(404, "商品不存在");
        }

        // 修改商品
        tbProdMapper.updateById(tbProd);
        return R.OK();
    }

    @Override
    public R deleteAllProd(ArrayList<Integer> prodIds) {
        tbProdMapper.deleteBatchIds(prodIds);
        return R.OK();
    }

    @Override
    public R doUpProd(Integer prodId, Integer flag) {
        //-- 查询商品信息
        TbProd tbProd = tbProdMapper.selectById(prodId);
        if(tbProd == null) {
            return R.ERROR(404, "商品不存在");
        }

        //-- 更新上架状态
        tbProd.setProdOn(flag);
        tbProdMapper.updateById(tbProd);

        return R.OK();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public R doUpAllProd(ArrayList<Integer> prodIds) {
        for (Integer prodId : prodIds) {
            //-- 查询商品信息
            TbProd tbProd = tbProdMapper.selectById(prodId);
            if(tbProd == null) {
                return R.ERROR(404, "商品不存在");
            }
            //-- 更新上架状态
            tbProd.setProdOn(1);
            tbProdMapper.updateById(tbProd);
        }
        return R.OK();
    }

    @Override
    public R uploadProdImg(MultipartFile file) {
        //--1 获取文件的扩展名
        String extName = FileNameUtil.extName(file.getOriginalFilename());

        //--2 上传文件
        try {
            StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(), file.getSize(), extName, null);
            String url = "http://192.168.80.192:8888/" + storePath.getFullPath();
            System.out.println("upload:"+url);
            return R.OK(url);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return R.ERROR(500, "上传失败");
    }

    @Override
    public R getProdStock() {

        //-- 获取产品列表
        List<TbProd> tbProds = tbProdMapper.selectList(null);

        //-- 组成echarts数据
        List<String> xList = new ArrayList<>();
        List<Integer> yList = new ArrayList<>();

        for (TbProd tbProd : tbProds) {
            xList.add(tbProd.getProdName());
            yList.add(tbProd.getProdCount());
        }

        //-- 返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("xList", xList);
        map.put("yList", yList);

        return R.OK(map);
    }

    @Override
    public R getProdPrice() {
        //-- 获取产品列表
        List<TbProd> tbProds = tbProdMapper.selectList(null);

        //-- 组成echarts数据
        List<String> xList = new ArrayList<>();
        List<Double> yList = new ArrayList<>();

        for (TbProd tbProd : tbProds) {
            xList.add(tbProd.getProdName());
            yList.add(tbProd.getProdPrice());
        }

        //-- 返回数据
        Map<String, Object> map = new HashMap<>();
        map.put("xList", xList);
        map.put("yList", yList);

        return R.OK(map);
    }


}
